package plugin

import (
	"net/http"
	"sync"
	"time"

	"commonUtils/utils"
	"commonUtils/web"
)

type PluginManager struct {
	lock    sync.RWMutex
	Plugins []func(next http.Handler) http.Handler
}

var inst *PluginManager

func Manager() *PluginManager {
	if inst != nil {
		return inst
	}
	inst = &PluginManager{}
	inst.Regist("loger", inst.loger)
	inst.Regist("session", inst.session)
	return inst
}

func (p *PluginManager) Regist(name string, handle func(http.Handler) http.Handler) {
	p.lock.Lock()
	defer p.lock.Unlock()
	p.Plugins = append(p.Plugins, handle)
}

func (p *PluginManager) InstallHandler(handle func(http.ResponseWriter, *http.Request)) http.Handler {
	p.lock.RLock()
	defer p.lock.RUnlock()
	var ret http.Handler
	ret = http.HandlerFunc(handle)
	for _, plugin := range p.Plugins {
		ret = plugin(ret)
	}
	return ret
}

func (p *PluginManager) loger(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		start := time.Now()
		next.ServeHTTP(w, r)
		defer func() {
			utils.Debug("%s %s in %v", r.Method, r.URL.Path, time.Since(start))
		}()
	})
}

func (p *PluginManager) session(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		web.SessionStart(w, r)
		next.ServeHTTP(w, r)
	})
}
